Skip to content

Conversation

marko-bekhta
Copy link
Member

https://hibernate.atlassian.net/browse/HSEARCH-5464


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license
and can be relicensed under the terms of the LGPL v2.1 license in the future at the maintainers' discretion.
For more information on licensing, please check here.


@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-5464-Groundwork-for-pluggable-rest-clients-in-the-Elasticsearch-backend branch 7 times, most recently from aac26ce to 1d41060 Compare September 10, 2025 14:31
@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-5464-Groundwork-for-pluggable-rest-clients-in-the-Elasticsearch-backend branch 3 times, most recently from 3da3726 to 610c554 Compare September 16, 2025 21:10
@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-5464-Groundwork-for-pluggable-rest-clients-in-the-Elasticsearch-backend branch from 610c554 to 343b198 Compare October 13, 2025 21:12
@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-5464-Groundwork-for-pluggable-rest-clients-in-the-Elasticsearch-backend branch from 1a49649 to e91fd98 Compare October 16, 2025 08:02
@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-5464-Groundwork-for-pluggable-rest-clients-in-the-Elasticsearch-backend branch from e91fd98 to ae10272 Compare October 16, 2025 08:29
Copy link
Member Author

@marko-bekhta marko-bekhta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @yrodiere @lucamolteni 🙂 👋🏻

I've added some comments here and there in this PR in places that may be of interest.
Otherwise there's a lot of "noise", from moving packages and renaming.

This PR doesn't include the docs+migration guide updates. I was thinking about sending that separately, as this already has a lot of changes 🙂.

private final JsonObject body;

public ElasticsearchResponse(HttpHost host, int statusCode, String statusMessage, JsonObject body) {
public ElasticsearchResponse(String host, int statusCode, String statusMessage, JsonObject body) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is pretty straightforward, we only use the host to log the response, and it's an SPI ... so removing the apache class here should be "safe"

Comment on lines +20 to +23
* https://github.com/google/gson/issues/764 is supposedly fixed.
* Hence, we may not need the workaround anymore.
* This version will be used in the test so we'll notice if things are still broken, for the main code
* the workaround is in place through the GsonProviderHelper.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This GSON issue was fixed, but I kept the workaround for the main code "just in case".

Comment on lines 48 to 35
@Deprecated(since = "8.2", forRemoval = true)
default Optional<ElasticsearchVersion> configuredVersion() {
return ConfigurationProperty.forKey(ElasticsearchBackendSettings.VERSION)
.as(ElasticsearchVersion.class, ElasticsearchVersion::of)
.build().get(configurationPropertySource());
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we are pushing the rest client code to a different jar, we cannot keep using ElasticsearchVersion hence the deprecation... (otherwise we'd need to push the ElasticsearchVersion somewhere else so it would accessible by both client and backend jars ... and pushing it to the client common didn't feel right)

Comment on lines 878 to 882
wireMockRule1.stubFor( post( urlPathMatching( "/myIndex/myType/_search" ) )
.withRequestBody( equalToJson( payload ) )
.willReturn( elasticsearchResponse().withStatus( 401 )
.withHeader( "www-authenticate", "Basic realm=\"IT Realm\"" ) ) );

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one might be interesting to know 🙂 elasticsearch-java client does not support "preemptive authentication" so it doesn' send the credentials right away, and it was causing the test to fail as the client never receied a 401 to send credentials.

Comment on lines 18 to 21
@SuppressJQAssistant(
reason = "Apache HTTP Client 5 uses a lot of classes/interfaces in the impl packages to create builders/instances etc. "
+ "So while it is bad to expose impl types ... in this case it's what Apache Client expects users to do?")
public interface ElasticsearchHttpClientConfigurationContext {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More of an FYI 🙈

org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder

* <p>
* Defaults to no request timeout.
*/
public static final String REQUEST_TIMEOUT = "request_timeout";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the idea here is to push any more-or-less client specific config properties to corresponding client impl modules.
with the apache based clients these are duplicated, but that might not be the case with other impls. So better stay safe 🙂


Map<String, String> queryParameters();

void overrideHeaders(Map<String, List<String>> headers);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for aws signing I just reshuffled the existing code to remove any apache specifics and push them to the client impls. Since we just need to set a few headers that signing might produce, this seems pretty straightforward.

Comment on lines +67 to +72
if ( entity instanceof AsyncEntityProducer producer ) {
if ( !producer.isRepeatable() ) {
throw new AssertionFailure( "Cannot sign AWS requests with non-repeatable entities" );
}
return new HttpAsyncEntityProducerInputStream( producer, 1024 );
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is a bit annoying as there seems to be no easier/simpler way to get the entity out of the request, but well ... it is what it is 🙂 🤷🏻

*
* @author Sanne Grinovero (C) 2017 Red Hat Inc.
*/
final class GsonHttpEntity implements HttpEntity, AsyncEntityProducer {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the apache client 5 apis changed a bit so these gson entities were updated a bit 🙂
the tests are passing and all seems good, but if anyone would want to have an extra look, that would be nice 🙂

Comment on lines 23 to 48
@SuppressWarnings("removal")
@Deprecated(since = "8.2", forRemoval = true)
public interface ElasticsearchHttpClientConfigurer
extends org.hibernate.search.backend.elasticsearch.client.rest.ElasticsearchHttpClientConfigurer {

/**
* Configure the HTTP Client.
* <p>
* This method is called once for every configurer, each time an Elasticsearch client is set up.
* <p>
* Implementors should take care of only applying configuration if relevant:
* there may be multiple, conflicting configurers in the path, so implementors should first check
* (through a configuration property) whether they are needed or not before applying any modification.
* For example an authentication configurer could decide not to do anything if no username is provided,
* or if the configuration property {@code my.configurer.enabled} is {@code false}.
*
* @param context A configuration context giving access to the Apache HTTP client builder
* and configuration properties in particular.
*/
void configure(ElasticsearchHttpClientConfigurationContext context);

@Override
default void configure(
org.hibernate.search.backend.elasticsearch.client.rest.ElasticsearchHttpClientConfigurationContext context) {
configure( new ElasticsearchHttpClientConfigurationContextDelegate( context ) );
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's how I went about making existing configurers work when the Search code internally only calls the "new configurer" method.

@marko-bekhta marko-bekhta force-pushed the feat/HSEARCH-5464-Groundwork-for-pluggable-rest-clients-in-the-Elasticsearch-backend branch from e347a5f to 2e6dca2 Compare October 16, 2025 20:30
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
78.6% Coverage on New Code (required ≥ 80%)
25.5% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant